import React, { ChangeEvent, useEffect, useState } from 'react';
import utils from '../../../utils';
import {ImageHelper as icon} from '../../../helper/ResourceHelper';
import { Breadcrumb, Button, Card, CardImg, Col, Container, Dropdown, Form, FormGroup, Image, InputGroup, Row, Toast } from 'react-bootstrap';
import MFile from './model/MFile';
import fileservice from '../../../services/fileservice';
import {PopupDialog} from '../../../components/common';
import "./index.css";
import networkutil from '../../../utils/network';
import { Id, toast } from 'react-toastify';
import { useNavigate } from 'react-router-dom';

function FileManager(){

    const [fileList,setFileList] = useState<Array<any>>([]);
    const [isEmpty,setIsEmpty] = useState<boolean>(false);
    const [queriedPath,setQueriedPath] = useState<string|any>("/");
    const [selectedFile,setSelectedFile] = useState<File|null>(null);
    var toastId:Id|null;

    const navigate = useNavigate()

    useEffect(()=>{
        console.debug("documents")
        listFiles();
    },[isEmpty,queriedPath])
    
    const listFiles = ()=> {
        utils.network.get("/files/list",{queries:{path:queriedPath}}).then((res:any)=>{
            var files = new Array<MFile>();
            for(var i=0;i<res.length;i++){
                var file = res[i];
                files.push(new MFile({
                    name:file.name,
                    filesize:file.size,
                    createTime:file.createtime,
                    isDir:file.isDictory,
                    idx:file.itemIdx,
                    path:file.path,
                    url:file.url,
                    type:file.type,
                }))
            }
            files = files.sort((f1,f2)=>{
                return f1.idx - f2.idx;
            })
            setFileList(files);
            setIsEmpty(files.length === 0);
        })
    }

    const backToParent = ()=> {
        const lastIdx = queriedPath.lastIndexOf("/");
        if(lastIdx > -1){
            const updatedPath = queriedPath.substring(0,lastIdx);
            setQueriedPath(updatedPath);    
        }
    }

    const clickItem = (item:MFile,index:number)=>{
        if(item.url){
            //TODO: support move action and add permission
            let actions = [
                {
                    title:"View",
                    textStyle:{
                        color:'blue'
                    },
                    action:()=>{
                        if(item.isDir){
                            setQueriedPath(item.path);
                        }else{
                            const state = {"target":item.url,mediaType:item.type}
                            navigate("/document/detail",{state})
                        }
                    }
                },
                {
                    title:"Download",
                    textStyle:{
                        color:'blue'
                    },
                    action:()=>{
                        fileservice.downloadFile(item.url,item.filename).then((data)=>{
                        })
                    }
                },
                {
                    title:"Rename",
                    textStyle:{
                        color:'blue'
                    },
                    action:()=>{
                        PopupDialog.showRenameDialog(item.filename,(newValue:any)=>{
                            if(!newValue){
                                PopupDialog.showBSPopup({
                                    message:"Please input the new folder name!"
                                })
                                return;
                            }
                            utils.network.post("/files/rename",{params:{
                                filePath:item.path,
                                name:newValue,
                            }}).then(()=>{
                                listFiles();
                            })
                        });
                    }
                },
                {
                    title:"Copy URL",
                    textStyle:{
                        color:'blue'
                    },
                    action:()=>{
                        item.url && navigator.clipboard.writeText(item.url).finally(()=>{
                            PopupDialog.dismiss();
                            toast.info("Copied url to clipboard!")    
                        });
                    }
                },
                {
                    title:"Delete",
                    textStyle:{
                        color:"red"
                    },
                    action:()=>{
                        PopupDialog.showBSPopup({message:`Do you want to delete ${item.filename}?`,showCancelButton:true},()=>{
                            utils.network.delete("/files",{params:{
                                filePath:item.path,
                                isdir:item.isDir
                            }}).then(()=>{
                                listFiles();
                            }).catch((err)=>{
                                PopupDialog.showBSPopup({message:err.message||"unexpected error occured!"})
                            })   
                        })            
                    }
                }
            ];
            if(item.isDir){
                delete actions[1];
            }
            PopupDialog.showActions("",actions);
        }
    }

    const resetQueriedPath = ()=> {
        setQueriedPath("/");
    }

    const uploadFile = ()=> {
        //TODO: add progress .
        console.debug("click upload file button");
        if(selectedFile){
            fileservice.uploadFileWithProgress(selectedFile,queriedPath,(progress:number)=>{
                console.debug("uploaded progress:"+progress);
                const progressStr = `${(progress*100).toFixed(2)}%`;
                
                if(!toastId){
                    toastId = toast(`Uploading: ${progressStr}`,{progress,autoClose:false});
                    toast.onChange = (callback)=>{
                        return ()=>{}
                    }

                }else{
                    toast.update(toastId!,{render:`Uploading ${progressStr}`,progress});
                }                
            }).then(()=>{
                toast.update(toastId!,{render:`Uploaded Successfully`,progress:1,autoClose:500});
                toastId = null;
                console.debug("uploaded completed");
                listFiles();
                var inputElement:any = document.getElementById("file-chooser");
                if(inputElement){
                    inputElement.value = "";
                } 
            }).catch((err)=>{
                console.debug("got error "+err);
                PopupDialog.showPopup({message:"Upload failed!"})
            });
        }
    }

    const onChangeFile = (event:ChangeEvent<HTMLInputElement>)=> {
        if(event.target.files){
            setSelectedFile(event.target.files[0]);
        }
    }
    //TODO: add delete function.
    return (<Container fluid className='d-flex flex-column'>
                {(queriedPath !== "/") ? (<Container fluid className='align-items-start p-0 m-0'>&nbsp;</Container>) : null}
                <Container fluid className='d-flex flex-row align-items-center justify-content-between p-0'>
                    <Breadcrumb>
                    {queriedPath !== "/" ? <Breadcrumb.Item onClick={resetQueriedPath}>...</Breadcrumb.Item>:null}
                    {queriedPath.split("/").filter((item:any)=>{return item !== ""}).map((path:any,idx:number,arr:Array<any>)=>{
                        return (<Breadcrumb.Item key={idx.toString()} onClick={backToParent} active={idx === arr.length-1}>{path}</Breadcrumb.Item>)
                    })}
                    </Breadcrumb>
                    <Button size='sm' variant='link' style={{fontSize:12}} onClick={()=>{
                        PopupDialog.showInput("Please input the folder name",(foldername:any)=>{
                            if(!foldername){
                                PopupDialog.showBSPopup({
                                    message:"Please input the new folder name!"
                                })
                                return;
                            }
                            utils.network.post("/files/createsub",{params:{
                                filePath:queriedPath,
                                name:foldername,
                            }}).then(()=>{
                                listFiles();
                            }).catch((err)=>{
                                PopupDialog.showBSPopup({message:err.message||"unexpected error occured!"})
                            })
                        });
                    }}>Create Folder</Button>
                </Container>
        {isEmpty ? (<>
        <p>This folder is empty</p>
        </>) :<Container fluid className='d-flex flex-row flex-wrap p-0 m-0'>{fileList.map((item:MFile,index)=>{
            return (<Card key={`list-item-${index}`} className='ms-2 mt-2 ' style={{maxWidth:120}} onClick={()=>{
                clickItem(item,index);
            }}>
            <Card.Body>
                {item.isDir ? <CardImg src={icon.folderIcon} style={{width:86}}/>:
                (item.type && item.type?.includes("image") && item.url && item.url?.length > 0 ? <img src={item.url} style={{width:80,height:100}}></img> : <CardImg src={icon.fileIcon} style={{width:86}}/>)}
            </Card.Body>
            <Card.Footer className='p-1 m-0'>
                <p className='file-name'>{item.filename}</p>
            </Card.Footer>
        </Card>)
        })}</Container>}
        <br/><br/>
        <Form.Group>
            <Form>
                <InputGroup>
                    <Form.Control 
                        id="file-chooser" 
                        type='file' 
                        name='filetoupload' 
                        onChange={onChangeFile}
                    /><br/>
                    <Button onClick={uploadFile}>Upload</Button>
                </InputGroup>
            </Form>
        </Form.Group>
    </Container>)
}

export default FileManager;